#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>

#define N 1000

int main() {
   int nteams_required = 2, max_thrds, tm_id;
   float sp_x[N], sp_y[N], sp_a = 0.0001f;
   double dp_x[N], dp_y[N], dp_a = 0.0001;

   max_thrds = omp_get_num_procs() / nteams_required;

   // 创建 2 个 teams，每个 team 处理不同精度计算
#pragma omp teams num_teams(nteams_required) thread_limit(max_thrds) private(tm_id)
   {
       tm_id = omp_get_team_num();

       if (omp_get_num_teams() != 2)
       {
           printf("error: Insufficient teams on host, 2 required\n");
           exit(0);
       }

       if (tm_id == 0) // 单精度计算 (SAXPY)
       {
#pragma omp parallel
           {
#pragma omp for
               for (int i = 0; i < N; i++) {
                   sp_x[i] = i * 0.0001f;
                   sp_y[i] = i;
               }

#pragma omp for simd simdlen(8)
               for (int i = 0; i < N; i++) {
                   sp_x[i] = sp_a * sp_x[i] + sp_y[i];
               }
           }

           if (tm_id == 1) // 双精度计算 (DAXPY)
           {

#pragma omp parallel
               {
#pragma omp for
                   for (int i = 0; i < N; i++) {
                       dp_x[i] = i * 0.0001;
                       dp_y[i] = i;
                   }

#pragma omp for simd simdlen(4)
                   for (int i = 0; i < N; i++) {
                       dp_x[i] = dp_a * dp_x[i] + dp_y[i];
                   }
               }
           }
       }
   }

    // 输出部分结果
    printf("i=%d sp|dp %.6f %.15f\n", N - 1, sp_x[N - 1], dp_x[N - 1]);
    printf("i=%d sp|dp %.6f %.15f\n", N / 2, sp_x[N / 2], dp_x[N / 2]);


    return 0;
}
